/*
 * block.h
 *
 * Copyright 2011 Pieter Agten
 *
 * This file is part of Yarf.
 *
 * Yarf is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Yarf is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Yarf.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * @file   block.h
 * @author Pieter Agten (pieter.agten@gmail.com)
 * @date   23 sep 2011
 * @brief  Defines the block_t data structure, which represents a straight line
 *         to be printed.
 */

#ifndef BLOCK_H
#define BLOCK_H

#include "yarf.h"
#include "util/fixed_point.h"

#include <stdbool.h>
#include <stdint.h>

/**
 * Data structure which represents a straight line to be printed.
 *
 * The planner component creates blocks based on g-code commands sent by the
 * host. These block are placed into a queue, which is read in a different
 * thread by the block handler component. The block handler is component that
 * actually executes blocks.
 *
@verbatim
A block's speed vs time plot is always shaped like a trapezoid:

             speed ^
                   |
   plateau speed --|---> +--------+
                   |    /          \                                
     entry speed --|-> +            \                               
                   |   |             + <-- exit speed = next block's
                   |   +-------------+                  entry speed
                   |______________________
                                 time --> 
@endverbatim
 * The acceleration and deceleration segments always have the same slope 
 * magnitude, as configured by the \a ACCELERATION configuration value.
 *
 */
typedef struct {
  unsigned int id;                    /**< Unique number to identify this block. Used for debugging purposes. */

  // Needed for block_handler:
  uint32_t nb_steps;                  /**< Total number of linear steps to take to execute this block. Each linear step consists of a single step of one or several stepper motors. */
  uint32_t nb_steps_completed;        /**< Number of linear steps of this block that have been executed so far. */
  steps_t steps[NUM_AXES];            /**< Total number of stepper motor steps to take for each axis. */
  void (*collision_handler)(uint8_t); /**< Pointer to a function which will be called if one of the end stop switches is hit while executing this block. */

  fxp16u16_t timer_ticks;            /**< The number of timer ticks to wait in between linear steps. This field changes during acceleration and deceleration while executing the block. */
  fxp16u16_t plateau_timer_ticks;    /**< The number of timer ticks to wait in between linear steps when the block execution is at its plateau (its maximum speed). */
  fxp16u16_t exit_timer_ticks;       /**< The number of timer ticks to wait in between linear steps at the end of the block execution (at the end of deceleration). This value is needed to prevent glitches while decelerating due to numerical round-off errors. */
  uint16_t acceleration_step;        /**< Indicates the current position on the linear acceleration ramp which starts at speed 0 and linearly accelerates according to a constant acceleration. */
  uint16_t acceleration_end;         /**< Linear step number at which to stop accelerating. */
  uint32_t deceleration_start;       /**< Linear step number at which to start decelerating. */


  // For avoiding duplicate calculations:
  float distance_mm;                 /**< Distance in millimeters of the movement represented by this block. */
  float mm_ticks_per_step_min;       /**< Average distance in millimeters traveled by each linear step, multiplied by the \a RTTIMER_TICKS_PER_MIN constant. */
  float direction[NUM_AXES];         /**< Four-dimensional unit direction vector (containing the direction cosines for each axis) of the movement represented by this block. */
  speed_t plateau_speed;             /**< The speed in mm/min when the block execution is at its plateau (its maximum speed). */
  
#if PLANNER_LOOKAHEAD
  speed_t entry_speed;               /**< Entry speed in mm/min at the start of the block execution (at the start of acceleration). Used by the planner and lookahead components to calculate the ticks and acceleration variables above. */
  speed_t max_entry_speed;           /**< Entry speed in mm/min at the end of the block execution (at the end of deceleration). Used by the planner and lookahead components to calculate the ticks and acceleration variables above. */

  bool plateau_speed_always_reachable; /**< Flag set and used by the lookahead component, indicating whether this block is long enough to be able to reach its plateau speed for sure.  */
  bool recalculate; /**< Flag set and used by the lookahead component, to indicate that the entry_speed field of this block was changed and that the timer and acceleration fields need to be updated accordingly. */
#endif

#if ADVANCE_ALGORITHM
  bool use_advance;            /**< Whether to use the advance pressure management system for this block. */
//  uint32_t advance_multiplier; /**< A precalculated value to speed up the advance steps calculation. */
  float advance_multiplier;
  int32_t advance;            /**< Number of steps to advance the extruder to obtain the desired flow rate. This is the result of the advance pressure management calculations. */
#endif
} block_t;

#endif //BLOCK_H
